package com.blockchain.controller;

import com.blockchain.model.Comments;
import com.blockchain.model.Follow;
import com.blockchain.model.Posts;
import com.blockchain.model.User;
import com.blockchain.repository.CommentRepository;
import com.blockchain.repository.FollowRepository;
import com.blockchain.repository.PostsRepository;
import com.blockchain.repository.UserRepository;
import com.blockchain.service.dto.CommentDTO;
import com.blockchain.service.dto.PostDTO;
import com.blockchain.service.dto.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@RestController
public class PostController {

    @Autowired
    private CommentRepository commentRepository;
    @Autowired
    private PostsRepository postsRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private FollowRepository followRepository;
    @PostMapping("/api/create_post")
    public ResponseEntity<String> createPost(@RequestParam("title") String title,
                                             @RequestParam("summary") String summary,
                                             @RequestParam("content") String content,
                                             @RequestParam("imageUrl") String imageUrl,
                                             @RequestParam("username") String username,
                                             @RequestParam("tags") String tagsString){
        try {
            Posts posts=new Posts();
            posts.setTitle(title);
            posts.setContent(content);
            posts.setSummary(summary);
            posts.setCoverUrl(imageUrl);
            User user=userRepository.findByUsername(username);
            posts.setAuthor(user);
            LocalDateTime time=LocalDateTime.now();
            posts.setCreatedAt(Timestamp.valueOf(time));
            posts.setUpdatedAt(Timestamp.valueOf(time));
            posts.setTags(tagsString);
            postsRepository.save(posts);
            return ResponseEntity.ok().body("测试成功");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/blog_details")
    public ResponseEntity<PostDTO> getBlogDetails(@RequestParam("post_id") int post_id){
        try {
            Posts posts=postsRepository.findByPostId(post_id);
            User user=posts.getAuthor();
            UserDTO userDTO=new UserDTO();
            userDTO.setAvatarUrl(user.getAvatarUrl());
            userDTO.setIntroduce(user.getIntroduce());
            userDTO.setUsername(user.getUsername());
            userDTO.setUser_id(user.getUserId());
            PostDTO postDTO=new PostDTO();
            postDTO.setAuthor(userDTO);
            postDTO.setContent(posts.getContent());
            postDTO.setTags(posts.getTags());
            postDTO.setTitle(posts.getTitle());
            postDTO.setCreatedAt(posts.getCreatedAt());
            postDTO.setUpdatedAt(posts.getUpdatedAt());
            postDTO.setId(Long.valueOf(posts.getPostId()));
            return ResponseEntity.ok().body(postDTO);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/api/get_followed_posts")
    public ResponseEntity<Page<PostDTO>> getFollowedPosts(@RequestParam("user_id") int user_id,
                                                          @RequestParam(defaultValue = "0") int page,
                                                          @RequestParam(defaultValue = "20") int size){
        Pageable pageable= PageRequest.of(page,size);
        User user=userRepository.findByUserId(user_id);
        List<Follow> followList=followRepository.findByFollower(user);
        List<User> userList=new ArrayList<>();
        for(Follow follow:followList){
            userList.add(follow.getFollowed());
        }
        List<Posts> postsList= new ArrayList<>();
        for (User user1 : userList) {
            List<Posts> userPosts = postsRepository.findByAuthorOrderByCreatedAtDesc(user1);
            postsList.addAll(userPosts);
        }
        List<PostDTO> postDTOList = new ArrayList<>();
        for (Posts post : postsList) {
            PostDTO postDTO = new PostDTO();
            postDTO.setId(Long.valueOf(post.getPostId()));
            User user1=post.getAuthor();
            UserDTO userDTO=new UserDTO();
            userDTO.setAvatarUrl(user1.getAvatarUrl());
            userDTO.setIntroduce(user1.getIntroduce());
            userDTO.setUsername(user1.getUsername());
            userDTO.setUser_id(user1.getUserId());
            postDTO.setAuthor(userDTO);
            postDTO.setContent(post.getContent());
            postDTO.setTags(post.getTags());
            postDTO.setTitle(post.getTitle());
            postDTO.setCreatedAt(post.getCreatedAt());
            postDTO.setUpdatedAt(post.getUpdatedAt());
            postDTO.setId(Long.valueOf(post.getPostId()));
            postDTO.setCoverUrl(post.getCoverUrl());
            // 设置其他属性...
            postDTOList.add(postDTO);
        }
        Page<PostDTO> postDTOS= new PageImpl<>(postDTOList,pageable,postDTOList.size());
        return ResponseEntity.ok().body(postDTOS);
    }
    @GetMapping("/blogs")
    public ResponseEntity<Page<PostDTO>> getPostsByAuthor(@RequestParam int author_id,
                                                        @RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            User author=userRepository.findByUserId(author_id);
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByAuthorOrderByCreatedAtDesc(author,pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }
    @GetMapping("/all_blogs")
    public ResponseEntity<Page<PostDTO>> getPosts(@RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findAllByOrderByCreatedAtDesc(pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }
    @GetMapping("/key_blogs")
    public ResponseEntity<Page<PostDTO>> getPostsByKey(@RequestParam(defaultValue = "0") int page,
                                                       @RequestParam(defaultValue = "10") int size,
                                                       @RequestParam("keyword") String keyword){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByTitleOrContentOrAuthorUsernameContaining(keyword,pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/web_blogs")
    public ResponseEntity<Page<PostDTO>> getPostsByWeb(@RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByTagsContainingOrderByCreatedAtDesc("Web3.0",pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }@GetMapping("/smart_blogs")
    public ResponseEntity<Page<PostDTO>> getPostsBySmart(@RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByTagsContainingOrderByCreatedAtDesc("智能合约",pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }@GetMapping("/dapp_blogs")
    public ResponseEntity<Page<PostDTO>> getPostsByDApps(@RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByTagsContainingOrderByCreatedAtDesc("DApps",pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }@GetMapping("/coin_blogs")
    public ResponseEntity<Page<PostDTO>> getPostsByCoin(@RequestParam(defaultValue = "0") int page,
                                                        @RequestParam(defaultValue = "10") int size){
        try {
            Pageable pageable= PageRequest.of(page,size);
            Page<Posts> postsPage=postsRepository.findByTagsContainingOrderByCreatedAtDesc("Coin",pageable);
            Page<PostDTO> postDTOS=postsPage.map(post ->{
                PostDTO postDTO=new PostDTO();
                User user=post.getAuthor();
                UserDTO userDTO=new UserDTO();
                userDTO.setUser_id(user.getUserId());
                userDTO.setUsername(user.getUsername());
                postDTO.setAuthor(userDTO);
                postDTO.setTitle(post.getTitle());
                postDTO.setId(Long.valueOf(post.getPostId()));
                postDTO.setTags(post.getTags());
                postDTO.setSummary(post.getSummary());
                postDTO.setCoverUrl(post.getCoverUrl());
                postDTO.setCreatedAt(post.getCreatedAt());
                return postDTO;
            } );
            System.out.println(postsPage);
            return ResponseEntity.ok(postDTOS);
        }catch (Exception e){
            throw new RuntimeException("Failed to get posts: " + e.getMessage());
        }
    }
    @PostMapping("/api/post_comment")
    public ResponseEntity<String> postComment(@RequestBody CommentDTO commentDTO){
        try {
            Comments comments=new Comments();
            System.out.println(commentDTO.getPostId());
            System.out.println(commentDTO.getContent());
            comments.setPostId(commentDTO.getPostId());
            comments.setContent(commentDTO.getContent());
            comments.setUserId(commentDTO.getUserId());
            comments.create();
            comments.update();
            commentRepository.save(comments);
            return ResponseEntity.ok().body("评论发布完成");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/get_comments")
    public ResponseEntity<Page<CommentDTO>> getComments(@RequestParam("postId") int post_id,
                                                      @RequestParam(defaultValue = "0") int page,
                                                      @RequestParam(defaultValue = "20") int size){
        try {
            Pageable pageable=PageRequest.of(page,size);
            Page<Comments> page1=commentRepository.findByPostIdOrderByCreatedAtDesc(post_id,pageable);
            Page<CommentDTO> commentDTOS=page1.map(comments -> {
                CommentDTO commentDTO=new CommentDTO();
                User user=userRepository.findByUserId(comments.getUserId());
                UserDTO userDTO=new UserDTO();
                userDTO.setUsername(user.getUsername());
                userDTO.setAvatarUrl(user.getAvatarUrl());
                userDTO.setUser_id(user.getUserId());
                commentDTO.setCommentId(comments.getCommentId());
                commentDTO.setUserDTO(userDTO);
                commentDTO.setContent(comments.getContent());
                commentDTO.setPostId(comments.getPostId());
                commentDTO.setCreatedAt(comments.getCreatedAt());
                return commentDTO;
            });
            System.out.println(page1);
            return ResponseEntity.ok().body(commentDTOS);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/get_posts_counts")
    public ResponseEntity<Long> getPostsCounts(@RequestParam("user_id") int user_id){
        User user=userRepository.findByUserId(user_id);
        long counts=postsRepository.countByAuthor(user);
        return ResponseEntity.ok().body(counts);
    }
}
